﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;

namespace Restful.Net.Tests
{
    [TestFixture]
    public class AsyncExtensionsTests
    {
        [Test]
        public void MyTestMethod()
        {
            List<Task> tasks = new List<Task>();
            List<Task> tasks2 = new List<Task>();
            for (int x = 0; x < 10; x++)
            {
                Task<string> hello = new Task<string>(() => "Hello");

                Task whenCompleted = hello.WhenCompleted<string>(GetString).WhenCompleted<string>(GetString2).WhenCompleted(WriteConsole);
                tasks.Add(hello);
                tasks2.Add(whenCompleted);
            }

            tasks.ForEach(t => t.Start());

            Task.WaitAll(tasks2.ToArray());

        }

        private void WriteConsole(IAsyncResult result)
        {
            Task<string> t = (Task<string>)result;
            Console.WriteLine("{0} {1} {2}", result.CompletedSynchronously, Thread.CurrentThread.ManagedThreadId, t.Result);
        }

        private string GetString(IAsyncResult result)
        {
            Task<string> t = (Task<string>)result;
            Console.WriteLine("{0} {1}", result.CompletedSynchronously, Thread.CurrentThread.ManagedThreadId);
            return t.Result + " World";
        }

        private string GetString2(IAsyncResult result)
        {
            Task<string> t = (Task<string>)result;
            Console.WriteLine("{0} {1}", result.CompletedSynchronously, Thread.CurrentThread.ManagedThreadId);

            return t.Result + " again";
        }






    }


    public static class TaskExtensions
    {
        public static Task<TOutput> WhenCompleted<TOutput>(this IAsyncResult result, Func<IAsyncResult, TOutput> continuation)
        {
            return Task.Factory.FromAsync(result, continuation);
        }

        public static Task WhenCompleted(this IAsyncResult result, Action<IAsyncResult> continuation)
        {
            return Task.Factory.FromAsync(result, continuation);
        }
    }

}
